#################################################################################
#
# Copyright (c) 2006 Michigan State University
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#################################################################################

#################################################################################
#
#	Author:
#		Nathan Collins <npcollins@gmail.com>
#
#################################################################################

""" Handles cookies server-side.

Allows for read/writes from/to cookies. Also handles processing
of the RememberWindow and its tabs.
"""

__version__ = "1.0"

# imports
from Cookie import SimpleCookie
import cgi,os

def findCookie( cookieVars = {} ):
	"""
	Returns: dict

	Attempt to retrieve a cookie's values. If no cookie is present,
	then create one. Returns the cookie's values in a dictionary.
	"""

	# if there is a cookie, get it
	if os.environ.has_key('HTTP_COOKIE'):
		cookie = SimpleCookie(os.environ['HTTP_COOKIE'])
	# otherwise, create one
	else:
		cookie = SimpleCookie()

	# populate the cookie with variables if they aren't there
	for k,v in cookieVars.iteritems():
		if not cookie.has_key(k):
			cookie[k] = v
	
	return cookie

def setCookieVars(varDict):
	"""
	Returns: None
	Outputs: Cookie Headers

	Sets cookie based on key/values in passed dict.
	"""
	cookie = findCookie()

	for k,v in varDict.iteritems():
		cookie[k] = v
	
	print cookie

def getCookieVar(entryName):
	"""
	Returns: string

	Retrieves cookie value for entryname.
	"""
	cookie = findCookie()

	try:
		return cookie[entryName].value
	except:
		return ''

def getCookieList(entryName):
	"""
	Returns: list

	Attempts to retrieve a list from a cookie. Given a key, that value is pulled
	from the cookie and split using a colon (:) as a delimiter. The list is returned.
	"""
	cookie = findCookie({entryName:''})
	entry = cookie[entryName].value
	# convert to a list
	entryList = entry.split(':')
	entryList = [e.replace('\!',':') for e in entryList]  #  =P
	# return the entry list
	return entryList

# add value to list of items in cookie 
def addCookieList(entryName,value,listMax = 8):
	"""
	Returns: None
	Outputs: Cookie Headers

	Attempts to add a value to a key in the cookie using a colon (:) as
	a delimiter. Duplicate checking will prevent two of the same values from
	being present in a list. If adding a value to the list would cause the
	list to exceed listMax, then the oldest value from the list is removed.
	The function prints out the HTML headers for the cookie before returning.
	"""
	oldList = getCookieList(entryName)
	cookie = findCookie()
	if value in oldList:
		oldList.remove(value)
	else:
		# add value to list
		if len(oldList) >= listMax: oldList = oldList[-(listMax-1):]

	newList = oldList + [value]
	# escape new list and concat
	newList = [e.replace(':','\!') for e in newList]  #  =P
	# set as cookie
	cookie[entryName] = ':'.join(newList)
	print cookie

def replaceCookieList(entryName, list):
	"""
	Returns: None
	Outputs: Cookie Headers

	Replaces a key in the cookie with a list delimited by a colon (:).
	"""
	cookie = findCookie()
	# escape new list and concat
	newList = [e.replace(':','\!') for e in list]  #  =P
	# set as cookie
	cookie[entryName] = ':'.join(newList)
	print cookie
	


##################################
# Remember Tab functions
##################################

def printTabs(retAsStr = 0):
	"""
	Print out new tabs.
	"""
	# get tab info from cookie
	rawTabs = getCookieList('remember')
	# to dict
	dictTabs = {}
	for t in rawTabs:
		if len(t.strip()) < 1: continue
		tempT = t.split('|')
		dictTabs[tempT[0]] = { 'recHash':tempT[1],'status':tempT[2],'active':tempT[3] }
	# generate tab info
	tabInfo = {}
	for t in range(1,8): # 1 through 7
		singleTab = { 'tabNum':t , 'recHash':'', 'status':'','active':'' }
		if dictTabs.has_key(str(t)):
			# add known data
			for k,v in dictTabs[str(t)].iteritems():
				singleTab[k] = v
		tabInfo[t] = singleTab
	# this next two lines dont really matter
	arrow = '?';
	arrowOnClick = ''
	final = genTab(arrowOnClick,'rwsh','remembertab plain clicky',arrow,0)
	# gen tabs
	for t in range(1,8):
		tab = tabInfo[t]
		cString = 'remembertab'
		onClick = 'markTabActive(%s); sendRemember(); checkMove(1)' % (t)
		bold = 0
		if tab['active'] == 'y' and tab['status'] == 'f':
			cString += ' vistab_f greenify'
		elif tab['active'] == 'y':
			cString += ' vistab_r greenify'
		if tab['status'] == 'r':
			cString += ' clicky plain'
			bold = 1
		elif tab['status'] == 'f' and tab['active'] != 'y':
			cString += ' clicky redish grey'
			bold = 1
		elif tab['status'] == 'f':
			cString += ' clicky redish'
			bold = 1
		else:
			cString += ' grey plain'
		final += genTab(onClick,'rtab'+str(tab['tabNum']),cString,tab['tabNum'],bold)

	# the 'forget all' tab
	final += genTab('forgetAll(); sendRemember(); slidePeek();', 'faTab', 'remembertab clicky plain redtext','X',1, 'Forget All Tabs')
	final = """
	<div id='remembertabs' class='f_left'>
	%s
	</div>
	""" % final
	if retAsStr != 0:
		return final
	else:
		print final
		return

def genTab(onClick,id,classString,num,bold = 0,title = ''):
	final = "<div id='%s' class='%s'>" % (id, classString)
	if bold != 0:
		final += '<b><a onClick="%s" title="%s">%s</a></b></div>' % (onClick,title,num)
	else:
		final += '<a onClick="%s">%s</a></div>' % (onClick,num)
	return final + '\n'

# get the rechash for the active tab
def getActiveHash():
	rawTabs = getCookieList('remember')
	for t in rawTabs:
		if len(t.strip()) == 0: continue
		split = t.split('|')
		if split[3] == 'y': return split[1]
	return ''

def getFirstAvailable():
	"""
	Find out the first available tab. -1 if none are available.
	"""
	# get the tab info from cookie
	rawTabs = getCookieList('remember')
	parsedTabs = {}
	# parse tab info
	for t in rawTabs:
		if len(t.strip()) < 1: continue
		tabSplit = t.split('|')
		parsedTabs[tabSplit[0]] = {'recHash':tabSplit[1],'status':tabSplit[2]}
	# find first available tab
	for t in range(1,8):
		if parsedTabs.has_key(str(t)):
			# if tab is available
			if parsedTabs[str(t)]['status'] != 'r':
				return t
		else:
			# first time use of tab
			return t
	# no available tab found
	return -1

def isHashForgotten(recHash):
	rawTabs = getCookieList('remember')
	for t in rawTabs:
		if len(t.strip()) == 0: continue
		split = t.split('|')
		if split[1] == recHash:
			if split[2] != 'r': return 1
	return 0

def markTabForgotten(tabNum):
	"""
	Mark a tab as forgotten, ready to be overwritten.
	"""
	tabNum = str(tabNum)
	list = getCookieList('remember')
	newlist = []
	# mark tabNum as forgotten
	for rec in list:
		recSplit = rec.split('|')
		if recSplit[0] == tabNum:
			recSplit[2] = 'f'
			rec = '|'.join(recSplit)
		newlist.append(rec)
	# print out the cookie
	replaceCookieList('remember',newlist)

def markTabRemembered(tabNum):
	"""
	Mark a tab as remembered, canceling a Forget click.
	"""
	tabNum = str(tabNum)
	list = getCookieList('remember')
	newlist = []
	# mark tabNum as remembered
	for rec in list:
		recSplit = rec.split('|')
		if recSplit[0] == tabNum:
			recSplit[2] = 'r'
			rec = '|'.join(recSplit)
		newlist.append(rec)
	# print out the cookie
	replaceCookieList('remember',newlist)

def markTabActive(tabNum):
	"""
	Mark a tab as active, all other tabs and not active.
	"""
	tabNum = str(tabNum)
	list = getCookieList('remember')
	newlist = []
	# mark tabNum as active
	for rec in list:
		recSplit = rec.split('|')
		if recSplit[0] == tabNum:
			recSplit[3] = 'y'
		else:
			recSplit[3] = 'n'
		rec = '|'.join(recSplit)
		newlist.append(rec)
	# print out the cookie
	replaceCookieList('remember',newlist)

def setTab(tabNum, recHash, active = 0):
	"""
	Set a given tab to hold a given metadata record.
	"""
	tabNum = str(tabNum)
	list = getCookieList('remember')
	newlist = []
	if active != 0:	active = 'y'
	else: active = 'n'
	# check for duplicate rechash, if so, do not add tab, just make existing active
	for rec in list:
		split = rec.split('|')
		if len(split) > 1 and split[1] == recHash:
			# dup found
			markTabActive(split[0])
			return
	# remove tabNum tab from list
	for rec in list:
		if rec.split('|')[0] != tabNum:
			if active == 'y' and len(rec.strip()) > 0:
				recSplit = rec.split('|')
				recSplit[3] = 'n'
				rec = '|'.join(recSplit)
			newlist.append(rec)
	# add recHash
	newlist.append(tabNum + '|' + recHash + '|r|' + active)
	# print out the cookie
	replaceCookieList('remember',newlist)


##################################

# eof

